<template>
  <lay-container fluid="true" class="dictionary-box">
    <div style="display: flex">
      <div :style="{ width: isFold ? `0px` : `300px` }" class="left-tree">
        <!-- tree -->
        <div v-show="!isFold">
          <lay-button type="normal" size="sm" @click="toAdd">
            <lay-icon type="layui-icon-addition"></lay-icon>新建
          </lay-button>
          <lay-button type="warm" size="sm" @click="toEdit">
            <lay-icon type="layui-icon-edit"></lay-icon>修改
          </lay-button>
          <lay-button type="danger" size="sm" @click="toDelete">
            <lay-icon type="layui-icon-delete"></lay-icon>删除
          </lay-button>
        </div>

        <lay-tree
          v-show="!isFold"
          style="margin-top: 10px"
          :data="data"
          :loading="loadingFlag"
          v-model:selectedKey="selectedKey"
          :showLine="showLine"
          :expandKeys="[1, 3, 4]"
          @node-click="handleClick"
        >
          <template #title="{ data }">
            <span :class="selectedKey == data.id ? 'isChecked' : ''">
              {{ data.title }}
            </span>
          </template>
        </lay-tree>
        <div class="isFold" @click="isFold = !isFold">
          &nbsp;<lay-icon v-if="!isFold" class="layui-icon-left"></lay-icon>
          <lay-icon v-else class="layui-icon-right"></lay-icon>
        </div>
      </div>
      <div style="flex: 1; padding: 10px; overFlow: auto">
        <lay-table
          :page="page"
          :height="'100%'"
          :columns="columns"
          :loading="loading"
          :default-toolbar="true"
          :data-source="dataSource"
          v-model:selected-keys="selectedKeys"
          @change="change"
          @sortChange="sortChange"
        >
          <template #isDefault="{ row }">
            <lay-tag :color="row.isDefault === 'Y' ? 'green' : 'gray'">
              {{ row.isDefault === 'Y' ? '是' : '否' }}
            </lay-tag>
          </template>
          <template v-slot:toolbar>
            <lay-input
              v-model="searchQuery.name"
              placeholder="请输入关键字查询"
              size="sm"
              :allow-clear="true"
              style="width: 200px; margin-right: 10px; background: #fff"
            ></lay-input>
            <lay-button type="normal" size="sm" @click="toSearch">
              查询
            </lay-button>
            <lay-button type="normal" size="sm" @click="toReset">
              重置
            </lay-button>
            <lay-button
              size="sm"
              type="primary"
              @click="changeVisible11('新增', null)"
              >新增</lay-button
            >
            <lay-button size="sm" type="danger" @click="toRemove"
              >删除</lay-button
            >
          </template>
          <template v-slot:operator="{ row }">
            <lay-button
              size="xs"
              border="green"
              border-style="dashed"
              @click="changeVisible11('编辑', row)"
              >编辑</lay-button
            >
            <lay-popconfirm
              content="确定要删除此字典项吗?"
              @confirm="() => confirmDelete(row)"
              @cancel="cancel"
            >
              <lay-button border="red" border-style="dashed" size="xs"
                >删除</lay-button
              >
            </lay-popconfirm>
          </template>
        </lay-table>
      </div>
    </div>
    <lay-layer v-model="visible11" :title="title" :area="['700px', '400px']">
      <div style="padding: 20px">
        <lay-form :model="model11" ref="layFormRef11" required>
          <lay-row>
            <lay-col md="12">
              <lay-form-item label="字典项名称" prop="dictLabel">
                <lay-input v-model="model11.dictLabel"></lay-input>
              </lay-form-item>
              <lay-form-item label="字典项值" prop="dictValue">
                <lay-input v-model="model11.dictValue"></lay-input>
              </lay-form-item>
              <lay-form-item label="样式类名" prop="cssClass">
                <lay-input v-model="model11.cssClass" placeholder="CSS样式类名"></lay-input>
              </lay-form-item>
            </lay-col>
            <lay-col md="12">
              <lay-form-item label="排序" prop="dictSort">
                <lay-input-number
                  style="width: 100%"
                  v-model="model11.dictSort"
                  position="right"
                ></lay-input-number>
              </lay-form-item>
              <lay-form-item label="是否默认" prop="isDefault">
                <lay-radio-group v-model="model11.isDefault">
                  <lay-radio value="Y">是</lay-radio>
                  <lay-radio value="N">否</lay-radio>
                </lay-radio-group>
              </lay-form-item>
              <lay-form-item label="备注" prop="remark">
                <lay-textarea
                  :rows="2"
                  allow-clear
                  placeholder="请输入备注"
                  v-model="model11.remark"
                ></lay-textarea>
              </lay-form-item>
            </lay-col>
          </lay-row>
        </lay-form>
        <div style="width: 100%; text-align: center">
          <lay-button size="sm" type="primary" @click="toSubmit"
            >保存</lay-button
          >
          <lay-button size="sm" @click="toCancel">取消</lay-button>
        </div>
      </div>
    </lay-layer>

    <lay-layer v-model="visible22" :title="title22" :area="['500px', '400px']">
      <div style="padding: 20px">
        <lay-form :model="model22" ref="layFormRef22" >
          <lay-form-item label="字典名称" prop="dictName" :required="true">
            <lay-input v-model="model22.dictName"></lay-input>
          </lay-form-item>
          <lay-form-item label="字典类型" prop="dictType" :required="true">
            <lay-input v-model="model22.dictType"></lay-input>
          </lay-form-item>
          <lay-form-item label="父级字典" prop="parentDictId">
            <lay-tree-select 
              v-model="model22.parentDictId" 
              :data="dictTypeTreeData" 
              placeholder="请选择父级字典"
              :disabled-keys="model22.dictId ? [model22.dictId] : []"
              check-strictly
              :replace-fields="{ key: 'id', title: 'title', children: 'children' }"
              allow-clear
              style="width: 100%"
              @change="handleParentDictChange"
            />
          </lay-form-item>
          <lay-form-item label="备注" prop="remark">
            <lay-textarea
              :rows="3"
              allow-clear
              placeholder="请输入备注"
              v-model="model22.remark"
            ></lay-textarea>
          </lay-form-item>
        </lay-form>
        <div style="width: 100%; text-align: center; margin-top: 20px">
          <lay-button size="sm" type="primary" @click="toSubmit"
            >保存</lay-button
          >
          <lay-button size="sm" @click="toCancel">取消</lay-button>
        </div>
      </div>
    </lay-layer>
  </lay-container>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted, nextTick } from 'vue'
import { layer } from '@layui/layui-vue'
import { listByLimit, saveByLeader, queryDetail, delsByLeader, updateByLeader, delsByBatch, queryLaySelectTree, saveDictType, updateDictType, deleteDictType } from '../../../api/module/dictionary-manager';

// 初始化
onMounted(() => {
  loadDictTypeTree()
})

// 左侧字典类型树
const data = ref([])
// 用于下拉选择的字典类型树数据
const dictTypeTreeData = ref([])
const showLine = ref(false)
const selectedKey = ref('')
// 选中的节点
const selectedNode = ref({
  id: 0,
  title: '',
  dictType: ''
})
const isFold = ref(false)
const searchQuery = ref({
  name: ''
})

// 加载字典类型树
async function loadDictTypeTree() {
  try {
    loadingFlag.value = true
    const response = await queryLaySelectTree({})
    if (response.code === 200) {
      // 后端返回的数据在 data.nextLayer 中
      const treeData = response.data.nextLayer || []
      data.value = treeData
      // 为TreeSelect准备数据，确保数据结构正确
      dictTypeTreeData.value = treeData
      if (treeData.length > 0) {
        selectedKey.value = treeData[0].id
        // 确保选中节点包含dictType字段
        selectedNode.value = {
          ...treeData[0],
          dictType: treeData[0].dictType || treeData[0].dict_type || ''
        }
        loadDictData()
      }
    }
  } catch (error) {
    layer.msg('加载字典类型失败', { icon: 2 })
  } finally {
    loadingFlag.value = false
  }
}

function toReset() {
  searchQuery.value = {
    name: ''
  }
  loadDictData()
}

function handleClick(node: any) {
  selectedNode.value = JSON.parse(JSON.stringify(node))
  selectedKey.value = node.id
  // 确保字典类型字段正确传递 - 从节点数据中获取dictType
  // 后端返回的树形数据中，dictType字段应该直接存在于节点中
  if (node.coreField) {
    // 确保dictType字段正确设置
    selectedNode.value.dictType = node.coreField
  } else {
    // 如果节点中没有dictType，检查节点原始数据
    console.log('节点数据:', node)
    // 尝试从节点的其他属性中获取dictType
    if (node.originalDictType) {
      selectedNode.value.dictType = node.originalDictType
    } else if (node.coreField) {
      selectedNode.value.dictType = node.coreField
    } else {
      // 如果确实没有dictType，显示警告但继续加载
      console.warn('节点缺少dictType字段:', node)
      layer.msg('该节点缺少字典类型信息，可能无法正确加载数据', { icon: 3, time: 2000 })
    }
  }
  loadDictData()
}

// TreeSelect父级字典选择变化事件
function handleParentDictChange(value: any) {
  console.log('父级字典选择变化:', value)
  model22.value.parentDictId = String(value)
}

// 删除字典类型
async function toDelete() {
  if (selectedKey.value == '') {
    layer.msg('您未选择字典，请先选择要删除的字典', {
      icon: 3,
      time: 2000
    })
    return
  }
  
  layer.confirm(
    '您将删除所选中的字典 [ ' + selectedNode.value.title + ' ] ？',
    {
      title: '提示',
      btn: [
        {
          text: '确定',
          callback: async (id: any) => {
            try {
              const response = await deleteDictType(selectedNode.value.id)
              if (response.code === 200) {
                layer.msg('删除成功', { icon: 1 })
                loadDictTypeTree()
              } else {
                layer.msg(response.msg || '删除失败', { icon: 2 })
              }
            } catch (error) {
              layer.msg('删除失败', { icon: 2 })
            } finally {
              layer.close(id)
            }
          }
        },
        {
          text: '取消',
          callback: (id: any) => {
            layer.msg('您已取消操作')
            layer.close(id)
          }
        }
      ]
    }
  )
}

function toSearch() {
  page.current = 1
  loadDictData()
}

// 字典数据
const dataSource = ref([])
const loading = ref(false)
const loadingFlag = ref(true)
const selectedKeys = ref([])
const page = reactive({ current: 1, limit: 10, total: 0 })

// 加载字典数据
async function loadDictData() {
  if (!selectedNode.value.id) return
  
  loading.value = true
  try {
    const queryWhere = {
      pageIndex: page.current,
      pageSize: page.limit,
      requestBody: {
        dictType: selectedNode.value.dictType,
        dictLabel: searchQuery.value.name
      }
    }
    const response = await listByLimit(queryWhere)
    if (response.code === 200) {
      // 根据返回报文结构，数据在response.data.responseBody中
      dataSource.value = response.data.responseBody || []
      page.total = response.data.totalNum || 0
    }
  } catch (error) {
    layer.msg('加载字典数据失败', { icon: 2 })
  } finally {
    loading.value = false
  }
}

const columns = ref([
  { title: '选项', width: '55px', type: 'checkbox', fixed: 'left' },
  { title: '字典项名称', key: 'dictLabel', sort: 'desc' },
  { title: '字典项值', key: 'dictValue', sort: 'desc' },
  { title: '排序', key: 'dictSort', sort: 'desc' },
  { title: '是否默认', key: 'isDefault', sort: 'desc' },
  { title: '样式类名', key: 'cssClass', sort: 'desc' },
  { title: '创建时间', width: '120px', key: 'createTime', sort: 'desc' },
  {
    title: '操作',
    width: '150px',
    customSlot: 'operator',
    key: 'operator',
    fixed: 'right'
  }
])

const change = (pageInfo: any) => {
  page.current = pageInfo.current
  page.limit = pageInfo.limit
  loadDictData()
}
const sortChange = (key: any, sort: number) => {
  layer.msg(`字段${key} - 排序${sort}, 你可以利用 sort-change 实现服务端排序`)
}

const changeStatus = (isChecked: boolean, row: any) => {
  // 状态变更逻辑
  layer.msg('状态变更成功', { icon: 1 })
}

const model11 = ref({
  dictCode: 0,
  dictLabel: '',
  dictValue: '',
  dictSort: 0,
  remark: '',
  dictType: '',
  cssClass: '',
  listClass: '',
  isDefault: 'N'
})
const layFormRef11 = ref()
const visible11 = ref(false)
const title = ref('新增')
const changeVisible11 = (text: any, row: any) => {
  title.value = text
  if (row) {
    let info = JSON.parse(JSON.stringify(row))
    model11.value = info
  } else {
    model11.value = {
      dictCode: 0,
      dictLabel: '',
      dictValue: '',
      dictSort: 0,
      remark: '',
      dictType: selectedNode.value.dictType || '',
      cssClass: '',
      listClass: '',
      isDefault: 'N'
    }
  }
  visible11.value = !visible11.value
}

// 保存字典数据或字典类型
async function toSubmit() {
  try {
    if (visible11.value) {
      // 保存字典数据
      if (!selectedNode.value.id) {
        layer.msg('请先选择字典类型', { icon: 3 })
        return
      }
      
      model11.value.dictType = selectedNode.value.dictType
      
      let response
      if (title.value === '新增') {
        response = await saveByLeader(model11.value)
      } else {
        response = await updateByLeader(model11.value)
      }
      
      if (response.code === 200) {
        layer.msg('保存成功', { icon: 1, time: 1000 })
        visible11.value = false
        loadDictData()
      } else {
        layer.msg(response.msg || '保存失败', { icon: 2 })
      }
    } else if (visible22.value) {
      // 保存字典类型
      let response
      if (title22.value === '新建字典') {
        response = await saveDictType(model22.value)
      } else {
        response = await updateDictType(model22.value)
      }
      
      if (response.code === 200) {
        layer.msg('保存成功', { icon: 1, time: 1000 })
        visible22.value = false
        loadDictTypeTree()
      } else {
        layer.msg(response.msg || '保存失败', { icon: 2 })
      }
    }
  } catch (error) {
    layer.msg('保存失败', { icon: 2 })
  }
}

function toRemove() {
  if (selectedKeys.value.length == 0) {
    layer.msg('您未选择数据，请先选择要删除的字典项', { icon: 3, time: 2000 })
    return
  }
  
  layer.confirm('您将删除所有选中的字典项？', {
    title: '提示',
    btn: [
      {
        text: '确定',
        callback: async (id: any) => {
          try {
            const response = await delsByBatch(selectedKeys.value)
            if (response.code === 200) {
              layer.msg('删除成功', { icon: 1 })
              loadDictData()
            } else {
              layer.msg(response.msg || '删除失败', { icon: 2 })
            }
          } catch (error) {
            layer.msg('删除失败', { icon: 2 })
          } finally {
            layer.close(id)
          }
        }
      },
      {
        text: '取消',
        callback: (id: any) => {
          layer.msg('您已取消操作')
          layer.close(id)
        }
      }
    ]
  })
}

function toAdd() {
  visible22.value = true
  title22.value = '新建字典'
  model22.value = {
    dictName: '',
    dictType: '',
    remark: '',
    parentDictId: String(selectedNode.value.id)|| '0'
  }
}

async function toEdit() {
  if (!selectedNode.value.id) {
    layer.msg('请先选择要修改的字典', { icon: 3 })
    return
  }
  
  try {
    // 调用接口获取字典类型详情
    const response = await queryDetail(selectedNode.value.id)
    if (response.code === 200) {
      const detail = response.data
      // 根据实体类字段名获取父节点ID
      const parentDictId = detail.parentDictId || 0
      
      title22.value = '修改字典'
      model22.value = {
        dictId: detail.dictId || selectedNode.value.id,
        dictName: detail.dictName || selectedNode.value.title,
        dictType: detail.dictType || selectedNode.value.dictType,
        remark: detail.remark || '',
        parentDictId: parentDictId
      }
      visible22.value = true
      // 延迟设置TreeSelect选中状态，确保组件已渲染完成
      setTimeout(() => {
        model22.value.parentDictId = String(parentDictId);
      }, 100)
    } else {
      layer.msg(response.msg || '获取详情失败', { icon: 2 })
    }
  } catch (error) {
    layer.msg('获取详情失败', { icon: 2 })
  }
}

// 在树形数据中查找节点
function findNodeById(nodes: any[], id: number): any {
  for (const node of nodes) {
    if (node.id === id) {
      return node
    }
    if (node.children && node.children.length > 0) {
      const found = findNodeById(node.children, id)
      if (found) return found
    }
  }
  return null
}

function confirm() {
  layer.msg('您已成功删除')
}
function cancel() {
  layer.msg('您已取消操作')
}

function toCancel() {
  visible11.value = false
  visible22.value = false
}

// 删除单个字典项
async function confirmDelete(row: any) {
  try {
    const response = await delsByBatch([row.dictCode])
    if (response.code === 200) {
      layer.msg('删除成功', { icon: 1 })
      loadDictData()
    } else {
      layer.msg(response.msg || '删除失败', { icon: 2 })
    }
  } catch (error) {
    layer.msg('删除失败', { icon: 2 })
  }
}

const model22 = ref({
  dictId: 0,
  dictName: '',
  dictType: '',
  remark: '',
  parentDictId: '0'
})
const layFormRef22 = ref()
const visible22 = ref(false)
const title22 = ref('新建字典')
</script>

<style scoped>
.dictionary-box {
  width: calc(100vw - 240px);
  height: calc(100vh - 110px);
  margin-top: 10px;
  box-sizing: border-box;
  background-color: #fff;
  overflow: hidden;
}
.left-tree {
  display: inline-block;
  padding: 20px 15px 0 5px;
  height: 1200px;
  border-right: 1px solid #e6e6e6;
  box-sizing: border-box;
  position: relative;
}
/* todo layui-tree-entry 设置无效 */
.layui-tree-entry {
  position: relative;
  padding: 10px 0;
  height: 20px;
  line-height: 20px;
  white-space: nowrap;
}
.isFold {
  position: absolute;
  top: 36%;
  right: -10px;
  width: 26px;
  height: 26px;
  line-height: 26px;
  border-radius: 13px;
  background-color: #fff;
  border: 1px solid #e6e6e6;
  cursor: pointer;
}

.search-input {
  display: inline-block;
  width: 98%;
  margin-right: 10px;
}

.isChecked {
  display: inline-block;
  background-color: #e8f1ff;
  color: red;
}
</style>